package com.hc.util;


import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.List;

import org.apache.commons.compress.archivers.tar.TarArchiveEntry;
import org.apache.commons.compress.archivers.tar.TarArchiveOutputStream;
import org.apache.commons.compress.utils.IOUtils;
import org.tukaani.xz.ARMOptions;
import org.tukaani.xz.FilterOptions;
import org.tukaani.xz.LZMA2Options;
import org.tukaani.xz.X86Options;
import org.tukaani.xz.XZOutputStream;

public class CompressUtil {

	public static void pack(String infileDir, String outFileDir, String filename)
			throws IOException {
		XZCompress(tarCompress(infileDir, outFileDir, filename), outFileDir,
				filename);
	}

	public static void packByList(List<String> list, String outFileDir,
			String filename) throws IOException {
		XZCompress(tarCompressByList(list, outFileDir, filename), outFileDir,
				filename);
	}

	public static File tarCompressByList(List<String> list, String outFileDir,
			String filename) throws IOException {
		File outFile = new File(outFileDir + "/" + filename + ".tar");
		if (!outFile.exists()) {
			outFile.createNewFile();
		}
		FileOutputStream out = new FileOutputStream(outFile);
		TarArchiveOutputStream os = new TarArchiveOutputStream(out);
		if (list == null || list.size() < 0) {
			return null;
		}
		for (String file : list) {
			
			
			try {
				os.putArchiveEntry(new TarArchiveEntry(new File(file)));
				IOUtils.copy(new FileInputStream(file), os);
				os.closeArchiveEntry();

			} catch (FileNotFoundException e) {
				e.printStackTrace();
			} catch (IOException e) {
				e.printStackTrace();
			} catch (Exception e) {
				e.printStackTrace();
			}
		}

		if (os != null) {
			os.flush();
			os.close();
		}
		return outFile;
	}
	
	public static void deleteFile(String path) {
		File file = new File(path);
		if(file.exists()) {
			file.delete();
		}
		
	}

	public static File tarCompress(String fileDir, String outFileDir,
			String filename) throws IOException {

		File[] sources = seachFiles(fileDir);
		FileOutputStream out = null;
		File outFile = new File(outFileDir + "/" + filename + ".tar");
		out = new FileOutputStream(outFile);

		TarArchiveOutputStream os = new TarArchiveOutputStream(out);
		for (File file : sources) {
			try {
				os.putArchiveEntry(new TarArchiveEntry(file));
				IOUtils.copy(new FileInputStream(file), os);
				os.closeArchiveEntry();

			} catch (FileNotFoundException e) {
				e.printStackTrace();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}

		if (os != null) {
			os.flush();
			os.close();
		}

		return outFile;
	}

	public static void XZCompress(File infile, String fileDir, String filename)
			throws IOException {

		ARMOptions arm = new ARMOptions();
		LZMA2Options lzma2 = new LZMA2Options();
		lzma2.setPreset(9);
		lzma2.setDictSize(LZMA2Options.DICT_SIZE_MIN);
		FilterOptions[] options = { arm, lzma2 };
		FileInputStream inputStream = new FileInputStream(infile);
		FileOutputStream outputStream = new FileOutputStream(new File(fileDir
				+ "/" + filename + ".xz"));
		// System.out.println("Encoder memory usage: "
		// + FilterOptions.getEncoderMemoryUsage(options) + " KiB");
		// System.out.println("Decoder memory usage: "
		// + FilterOptions.getDecoderMemoryUsage(options) + " KiB");
		XZOutputStream xzOutputStream = new XZOutputStream(outputStream,
				options);
		byte[] buf = new byte[1024 * 1024];
		int size;
		try {
			while ((size = inputStream.read(buf)) != -1) {
				xzOutputStream.write(buf, 0, size);
			}
		} finally {
			xzOutputStream.finish();
			xzOutputStream.close();
			outputStream.close();
			inputStream.close();
		}
		System.out.println("ok!");

	}

	public static File[] seachFiles(String path) {

		File fileDir = new File(path);
		if (fileDir.isFile()) {
			return new File[] { fileDir };
		} else {
			return fileDir.isDirectory() ? fileDir.listFiles() : null;
		}
		// if (fileDir.isDirectory() == false) {
		// return null;
		// }
		// File[] files = fileDir.listFiles();
		// for (File file : files) {
		// System.out.println(file.getName());
		// }
	}

	public static void main(String[] args) {

		String base = System.getProperty("user.dir");
		try {
			CompressUtil.pack(base + "/test", base, "test");
		} catch (IOException e) {
			e.printStackTrace();
		}

	}

}
